package Client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import common.Ranking;
import common.RankingEntry;
import common.UserMap;
import common.UserMap.BoxType;
import common.exception.ExtinctionException;


@SuppressWarnings("serial")
public class FGUI extends JFrame implements UI {

	private final int MAP_SIZE = 40;
	private final int H_SIZE = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth() -50;
	private final int V_SIZE = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight() -50;
	private JPanel board, interact;
	private JMenuBar menu;
	private JFrame popup, error;
	
	private JButton[] buttonMap = new JButton[this.MAP_SIZE*this.MAP_SIZE];
	private UserMap myMap;
	private ImageIcon DINOHERB, DINOCARN ,MEAT , VEGE, myDinoIcon;
	
	private Client logic;
	private MapHandler mapHandler;
	private ActionHandler actionHandler;
	private Integer[] myDinos;

	
	
	//COSTRUTTORE
	
	public FGUI(Client myClient){
		
		super("Isola dei Dinosauri");
		this.logic = myClient;
		
		setLayout(new BorderLayout());
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(this.H_SIZE, this.V_SIZE);
		
		this.actionHandler = new ActionHandler();
		this.mapHandler = new MapHandler();
		
		this.menu = new JMenuBar();
		this.menu.setPreferredSize(new Dimension(this.H_SIZE, this.V_SIZE / 30));
		
		JMenu game = new JMenu("Game");
		
		JMenuItem login = new JMenuItem("Login/Registrazione");
		login.setActionCommand("preLogin");
		login.addActionListener(this.actionHandler);
		
		JMenuItem inGame = new JMenuItem("Go into the match");
		inGame.setActionCommand("inGame");
		inGame.addActionListener(this.actionHandler);
		
		JMenuItem logout = new JMenuItem("Logout");
		logout.setActionCommand("logout");
		logout.addActionListener(this.actionHandler);
		
		JMenuItem outGame = new JMenuItem("Exit from match");
		outGame.setEnabled(false);
		outGame.setActionCommand("outGame");
		outGame.addActionListener(this.actionHandler);
		
		game.add(login);
		game.add(inGame);
		game.add(outGame);
		game.add(logout);
		
		this.menu.add(game);
		this.setJMenuBar(this.menu);
		
		Container pane = this.getContentPane();
		
		this.board = new JPanel();
		this.board.setLayout(new GridLayout(this.MAP_SIZE, this.MAP_SIZE));

		JScrollPane scroll = new JScrollPane(this.board);
		
		scroll.setViewportBorder(BorderFactory.createLineBorder(Color.black));
		scroll.setPreferredSize(new Dimension((int) (this.H_SIZE * 0.9), this.V_SIZE));
		

		this.interact = new JPanel();
		this.interact.setLayout(new BoxLayout(this.interact, BoxLayout.Y_AXIS));
		this.interact.setMinimumSize(new Dimension(this.H_SIZE / 10, this.V_SIZE));
		this.interact.setMaximumSize(new Dimension(this.H_SIZE / 10, this.V_SIZE));
		
		
		pane.add(scroll, BorderLayout.CENTER);
		pane.add(this.interact, BorderLayout.EAST);
		
		/*
		 * Icone 
		 */
		this.DINOHERB = new ImageIcon("src/res/herb.gif");
		this.DINOCARN = new ImageIcon("src/res/carn.gif");
		this.VEGE = new ImageIcon("src/res/grass-icon.png");
		this.MEAT = new ImageIcon("src/res/Meat-icon.png");
		/*
		 * 
		 */
		
		this.pack();
		this.setVisible(true);
	}
	
	
	
	//NOT LOGGED-IN
	
	@Override
	public void showPreLogin() {
		
		createPopup(300 , 180 , new BorderLayout());
		
		//PANNELLI
		JPanel westPanel = new JPanel();
		westPanel.setLayout(new BoxLayout(westPanel, SwingConstants.VERTICAL));
		westPanel.setMinimumSize(new Dimension(150 , 140));
		westPanel.setPreferredSize(new Dimension(150 , 140));
	
		JPanel eastPanel = new JPanel();
		eastPanel.setLayout(new BoxLayout(eastPanel, SwingConstants.VERTICAL));
		eastPanel.setMinimumSize(new Dimension(150 , 140));
		eastPanel.setPreferredSize(new Dimension(150 , 140));
		
		JPanel southPanel = new JPanel();
		southPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 40 , 0));
		southPanel.setMinimumSize(new Dimension(300 , 40));
		southPanel.setPreferredSize(new Dimension(300 , 40));
		
		
		//ETICHETTE
		JLabel usernameLabel = new JLabel("Username: ");
		usernameLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
	
		JLabel pswLabel = new JLabel("Password: ");
		pswLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

		//CAMPI
		JTextField nameField = new JTextField();
		nameField.setMinimumSize(new Dimension(140, 25));
		nameField.setPreferredSize(new Dimension(140, 25));
		nameField.setAlignmentX(Component.CENTER_ALIGNMENT);
		
		JPasswordField pswField = new JPasswordField();
		pswField.setMinimumSize(new Dimension(140, 25));
		pswField.setPreferredSize(new Dimension(140, 25));
		pswField.setAlignmentX(Component.CENTER_ALIGNMENT);
		
		
		//BOTTONI
		JButton loginButton = new JButton("Login");
		loginButton.addActionListener(this.actionHandler);
		loginButton.setActionCommand("login");
		loginButton.putClientProperty("username", nameField);
		loginButton.putClientProperty("passwd", pswField);

		JButton registrationButton = new JButton("Registrati");
		registrationButton.addActionListener(this.actionHandler);
		registrationButton.setActionCommand("register");
		registrationButton.putClientProperty("username", nameField);
		registrationButton.putClientProperty("passwd", pswField);
		
		//FILLING
		
		westPanel.add(Box.createRigidArea(new Dimension(0 , 20)));
		westPanel.add(usernameLabel);
		westPanel.add(Box.createRigidArea(new Dimension(0 , 30)));
		westPanel.add(pswLabel);
		westPanel.add(Box.createRigidArea(new Dimension(0 , 20)));
		
	
		eastPanel.add(Box.createRigidArea(new Dimension(0 , 20)));
		eastPanel.add(nameField);
		eastPanel.add(Box.createRigidArea(new Dimension(0 , 20)));
		eastPanel.add(pswField);
		eastPanel.add(Box.createRigidArea(new Dimension(0 , 20)));
		
		
		southPanel.add(loginButton , 0);
		southPanel.add(registrationButton , 1);
		
		this.popup.add(westPanel , BorderLayout.WEST);
		this.popup.add(eastPanel , BorderLayout.EAST);
		this.popup.add(southPanel , BorderLayout.SOUTH);
		this.popup.setVisible(true);
	}

	@Override
	public void showCredits() {
		// TODO Auto-generated method stub

	}

	
	//LOGGED
	
	public void fillInteract() {
		
		//BOTTONI
		
		JButton skipTurnButton = new JButton("Passa Turno");
		skipTurnButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		skipTurnButton.setActionCommand("skipTurn");
		skipTurnButton.addActionListener(this.actionHandler);
		skipTurnButton.setEnabled(true);
	
		JButton growButton = new JButton("Cresci");
		growButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		growButton.setActionCommand("grow");
		growButton.addActionListener(this.mapHandler);
		growButton.setEnabled(false);
		
		JButton eggButton = new JButton("Uovo");
		eggButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		eggButton.setActionCommand("egg");
		eggButton.addActionListener(this.mapHandler);
		eggButton.setEnabled(false);
		
		JButton rankingButton = new JButton("Classifica");
		rankingButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		rankingButton.setActionCommand("ranking");
		rankingButton.addActionListener(this.actionHandler);
		
		JButton playersButton = new JButton("Giocatori");
		playersButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		playersButton.setActionCommand("playersList");
		playersButton.addActionListener(this.actionHandler);
		
		
		//ETICHETTA
		JLabel playersLabel = new JLabel("Giocatori connessi:");
		playersLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

		
		//FILLING
		
		this.interact.add(Box.createRigidArea(new Dimension(0 , 25)));
		this.interact.add(skipTurnButton);
		this.interact.add(Box.createRigidArea(new Dimension(0 , 25)));
		this.interact.add(growButton);
		this.interact.add(Box.createRigidArea(new Dimension(0 , 25)));
		this.interact.add(eggButton);
		this.interact.add(Box.createRigidArea(new Dimension(0 , 25)));
		this.interact.add(rankingButton);
		this.interact.add(Box.createRigidArea(new Dimension(0 , 25)));
		this.interact.add(playersButton);
		this.interact.add(Box.createRigidArea(new Dimension(0 , 25)));
		this.interact.add(playersLabel);
		this.interact.add(Box.createRigidArea(new Dimension(0 , 5)));
		
		this.interact.revalidate();
		this.interact.repaint();
		this.interact.setVisible(true);


	}

	@Override
	public void showNewSpecies() {
		
		createPopup(450, 200, new BorderLayout());

		//PANNELLI
		JPanel speciesNamePanel = new JPanel();
		speciesNamePanel.setLayout(new BoxLayout(speciesNamePanel, BoxLayout.X_AXIS));
		speciesNamePanel.setSize(new Dimension(180, 200));
		
		JPanel speciesTypePanel = new JPanel();
		speciesTypePanel.setLayout(new GridLayout(2, 2));
		
		JPanel buttonPanel = new JPanel();
		
		
		//LABEL
		JLabel speciesNameLabel = new JLabel("Nome Specie:");
		speciesNameLabel.setAlignmentY(Component.CENTER_ALIGNMENT);
		
		
		//CAMPO SPECIE
		JTextField speciesNameField = new JTextField();
		speciesNameField.setAlignmentY(Component.CENTER_ALIGNMENT);
		speciesNameField.setMaximumSize(new Dimension(150, 30));
		speciesNameField.setPreferredSize(new Dimension(150, 30));
		
		
		//BOTTONI
		ButtonGroup groupButtons = new ButtonGroup();

		JRadioButton carnivoro = new JRadioButton();
		carnivoro.setActionCommand("c");
		
		JRadioButton erbivoro = new JRadioButton();
		erbivoro.setSelected(true);
		erbivoro.setActionCommand("e");
	
		JButton ok = new JButton("OK");
		ok.setMaximumSize(new Dimension(80 , 30));
		ok.setPreferredSize(new Dimension(80 , 30));
		ok.setActionCommand("newSpecies");
		ok.addActionListener(this.actionHandler);
		ok.putClientProperty("speciesName", speciesNameField);
		ok.putClientProperty("speciesType", groupButtons);
		
		
		//FILLING
		groupButtons.add(erbivoro);
		groupButtons.add(carnivoro);

		
		speciesTypePanel.add(new JLabel("Erbivora"));
		speciesTypePanel.add(erbivoro);
		speciesTypePanel.add(new JLabel("Carnivora"));
		speciesTypePanel.add(carnivoro);
		
		
		speciesNamePanel.add(Box.createRigidArea(new Dimension(20 , 0)));
		speciesNamePanel.add(speciesNameLabel);
		speciesNamePanel.add(Box.createRigidArea(new Dimension(20 , 0)));
		speciesNamePanel.add(speciesNameField);
		speciesNamePanel.add(Box.createRigidArea(new Dimension(20 , 0)));
		
		buttonPanel.add(ok);
		
		
		this.popup.add(speciesNamePanel , BorderLayout.CENTER);
		this.popup.add(speciesTypePanel , BorderLayout.EAST);
		this.popup.add(buttonPanel , BorderLayout.SOUTH);
		this.popup.validate();
		this.popup.repaint();
		this.popup.setVisible(true);
	}
	
	@Override
	public void showLogout() {
		// TODO Auto-generated method stub

	}
	
	//INGAME

	@Override
	public void createMap(){
		
		if (this.myMap == null)
			this.myMap = this.logic.getMap();
		
		else {
			this.board.removeAll();
			this.myMap = this.logic.getMap();
		}
	
		
		for (int id = 0 ; id < this.buttonMap.length ; id++){
			this.buttonMap[id] = new JButton();
			this.buttonMap[id].setMinimumSize(new Dimension(30 , 30));
			this.buttonMap[id].setPreferredSize(new Dimension(30, 30));
			this.buttonMap[id].addActionListener(this.mapHandler);
			
			this.board.add(this.buttonMap[id]);
		}
		
		
		int[] box = {0 , 0};
		for (int id = 0 ; id < this.buttonMap.length ; id++){
			box[0] = id % this.MAP_SIZE;
			box[1] = this.MAP_SIZE - 1 -(id / this.MAP_SIZE);
			this.buttonMap[id].putClientProperty("x" , box[0]);
			this.buttonMap[id].putClientProperty("y" , box[1]);
			this.buttonMap[id].putClientProperty("type" , this.myMap.typeOf(box));
			
			if (this.myMap.typeOf(box).equals(BoxType.DARK)){
				this.buttonMap[id].setEnabled(false);
				this.buttonMap[id].setBackground(Color.BLACK);
			}
			if (this.myMap.typeOf(box).equals(BoxType.LAND)){
				this.buttonMap[id].setBackground(Color.GREEN);
				this.buttonMap[id].setIcon(null);
			}
			
			if (this.myMap.typeOf(box).equals(BoxType.VEGE)){
				this.buttonMap[id].setBackground(Color.GREEN);
				this.buttonMap[id].setIcon(this.VEGE);
			}
			if (this.myMap.typeOf(box).equals(BoxType.WATER)){
//				this.buttonMap[id].setIcon(this.WATER);
				this.buttonMap[id].setEnabled(false);
				this.buttonMap[id].setBackground(Color.CYAN);
			}
		}
		this.board.setEnabled(true);
		this.board.revalidate();
		this.board.setVisible(true);
	}
	
	@Override
	synchronized public void refreshMap() {
		if (this.myMap == null)
			this.createMap();
		for (JButton b : this.buttonMap){
			
			if (b.getClientProperty("type") != null)
			{
				if (! b.getClientProperty("type").equals(null) &&
						! BoxType.DARK.equals(b.getClientProperty("type")) &&
						! BoxType.WATER.equals(b.getClientProperty("type"))){
					b.setBackground(Color.GRAY);
					if (BoxType.MEAT.equals(b.getClientProperty("type"))) b.setIcon(null);
				}
			}
			
				
		}
		
		this.myDinos = this.logic.dinosList();
		if (this.myDinos.length == 0){
			this.showExtinction();
			return;
		}
		
		for (Integer id : this.myDinos){
			UserMap view = this.logic.localView(id);
			
			Vector<?> stats = this.logic.dinoStat(id);
			int dimensione = (Integer) stats.get(5);
			int visuale;
			if (dimensione == 1)
				visuale =  2;
			else if (dimensione < 4){
				visuale =  3;
			}
			else {
				visuale =  4;
			}
			
			for (int i = view.getOriginX();i <= view.getOriginX() + 2*visuale;i++){
				for (int j = view.getOriginY();j <= view.getOriginY() + 2*visuale;j++){
					if (i < this.MAP_SIZE && j < this.MAP_SIZE){
						int idBox = this.MAP_SIZE * (this.MAP_SIZE - 1 - j) + i;
						int[] box = {i, j};
						this.buttonMap[idBox].putClientProperty("x" , i);
						this.buttonMap[idBox].putClientProperty("y" , j);
						this.buttonMap[idBox].putClientProperty("type" , view.typeOf(box));


						if (view.typeOf(box) != null){
							if (view.typeOf(box).equals(BoxType.LAND)){
								this.buttonMap[idBox].setBackground(Color.GREEN);
								this.buttonMap[idBox].setIcon(null);
								this.buttonMap[idBox].putClientProperty("energy", null);
								this.buttonMap[idBox].putClientProperty("idDino", null);
								this.buttonMap[idBox].setEnabled(true);
							}
							if (view.typeOf(box).equals(BoxType.WATER)){
								this.buttonMap[idBox].setEnabled(false);
								this.buttonMap[idBox].setBackground(Color.CYAN);
							}
							if (view.typeOf(box).equals(BoxType.MEAT)){
								this.buttonMap[idBox].setBackground(Color.GREEN);
								this.buttonMap[idBox].setIcon(this.MEAT);
								this.buttonMap[idBox].setToolTipText("Carogna. Energia: " + Integer.toString(view.valueOf(box)) );
								this.buttonMap[idBox].putClientProperty("energy" , view.valueOf(box));
								this.buttonMap[idBox].setEnabled(true);
							}
							if (view.typeOf(box).equals(BoxType.VEGE)){
								this.buttonMap[idBox].setBackground(Color.GREEN);
								this.buttonMap[idBox].setIcon(this.VEGE);
								this.buttonMap[idBox].setToolTipText("Vegetazione. Energia: " + Integer.toString(view.valueOf(box)) );
								this.buttonMap[idBox].putClientProperty("energy" , view.valueOf(box));
								this.buttonMap[idBox].setEnabled(true);
							}
							if (view.typeOf(box).equals(BoxType.DINO)){
								this.buttonMap[idBox].setBackground(Color.GREEN);

								Vector<?> dinoStats = this.logic.dinoStat(view.valueOf(box));
								String tooltip = "Dinosauro. Dimensione: " + dinoStats.get(5);
								if (dinoStats.size() > 6)
									tooltip = tooltip.concat(" Energia: " + dinoStats.get(6));
								this.buttonMap[idBox].setToolTipText(tooltip);
								this.buttonMap[idBox].putClientProperty("idDino" , view.valueOf(box));
								if ((Character)dinoStats.get(2) == 'c')
									this.buttonMap[idBox].setIcon(this.DINOCARN);
								else
									this.buttonMap[idBox].setIcon(this.DINOHERB);
								this.buttonMap[idBox].setEnabled(true);
							}
						}			
					}
				}
			}
			int idBoxDino = this.MAP_SIZE * (this.MAP_SIZE - 1 - (Integer)stats.get(4)) + (Integer)stats.get(3);
			this.buttonMap[idBoxDino].setActionCommand("");
			this.buttonMap[idBoxDino].setBackground(Color.GREEN);
			this.buttonMap[idBoxDino].setIcon(this.myDinoIcon);
			this.buttonMap[idBoxDino].putClientProperty("idDino" , id);
			this.buttonMap[idBoxDino].setEnabled(true);
		}


		
		this.board.setEnabled(true);
		this.board.revalidate();
	}

	public void changeTurn(String newUser, boolean myTurn) {
		
	
		
		String message = "Tocca a ";
		if (myTurn){
			message = message.concat("te. ");
			message = message.concat("Vuoi giocare?");
		} else
			message = message.concat(newUser);
			
			
		createPopup(350 , 250 , new BorderLayout());
		
		JPanel topPanel = new JPanel();
		topPanel.setMinimumSize(new Dimension(350 , 250));
		topPanel.setPreferredSize(new Dimension(350 , 250));
	
		JPanel bottomPanel = new JPanel();
		bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 0));
		bottomPanel.setMinimumSize(new Dimension(350 , 100));
		bottomPanel.setPreferredSize(new Dimension(350 , 100));
		
		JLabel messageLabel = new JLabel(message);
		messageLabel.setAlignmentX(CENTER_ALIGNMENT);
		messageLabel.setAlignmentY(CENTER_ALIGNMENT);
		
		if (myTurn){
			JButton use = new JButton("Si");
			use.addActionListener(this.actionHandler);
			use.setActionCommand("useTurn");
			use.setMinimumSize(new Dimension(80 , 30));
			use.setPreferredSize(new Dimension(80 , 30));
			
			JButton skip = new JButton("No");
			skip.addActionListener(this.actionHandler);
			skip.setActionCommand("skipTurn");
			skip.setMinimumSize(new Dimension(80 , 30));
			skip.setPreferredSize(new Dimension(80 , 30));
			
			bottomPanel.add(use , 0);
			bottomPanel.add(skip , 1);
		} else {
			JButton ok = new JButton("Ok");
			ok.addActionListener(this.actionHandler);
			ok.setActionCommand("closePopup");
			ok.setMinimumSize(new Dimension(80 , 30));
			ok.setPreferredSize(new Dimension(80 , 30));
			
			bottomPanel.add(ok);
		}
		
		topPanel.add(messageLabel);
		
		this.popup.add(topPanel , BorderLayout.NORTH);
		this.popup.add(bottomPanel , BorderLayout.CENTER);
		
		this.popup.validate();
		this.popup.repaint();
		this.popup.setVisible(true);
		
		showPlay();
	}

	public void showPlay(){
		
		if(this.logic.getTurn()){
			
			for (Component c :this.interact.getComponents()){
				if (c instanceof JButton){
					if ("skipTurn".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(true);}
					if ("grow".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(false);}
					if ("egg".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(false);}
				}
			}
		}
		
		else{
			for (JButton b : this.buttonMap)
				b.setEnabled(false);
			
			for (Component c :this.interact.getComponents()){
				if (c instanceof JButton){
					if ("skipTurn".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(false);}
					if ("grow".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(false);}
					if ("egg".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(false);}
				}
			}
		}
		
		refreshBoard();
		refreshInteract();
	}

	public void showExtinction() {
		
		createPopup(300 , 200 , new BorderLayout());
		this.popup.setTitle("Estinzione");
		
		this.board.setEnabled(false);
		for (JButton b : this.buttonMap)
			b.setEnabled(false);
		
		JPanel topPanel = new JPanel();
		topPanel.setMinimumSize(new Dimension(300 , 150));
		topPanel.setPreferredSize(new Dimension(300 , 150));
		
		JPanel bottomPanel = new JPanel();
		bottomPanel.setMinimumSize(new Dimension(300 , 50));
		bottomPanel.setPreferredSize(new Dimension(300, 50));
		
		JLabel label = new JLabel("La tua specie si e' estinta!");
		label.setAlignmentX(CENTER_ALIGNMENT);
		label.setAlignmentY(CENTER_ALIGNMENT);
		
		JButton ok = new JButton("OK");
		ok.setMaximumSize(new Dimension(80 , 30));
		ok.setPreferredSize(new Dimension(80 , 30));
		ok.setAlignmentX(CENTER_ALIGNMENT);
		ok.setAlignmentY(CENTER_ALIGNMENT);
		ok.setActionCommand("closePopup");
		ok.addActionListener(this.actionHandler);
		
		this.popup.add(label , BorderLayout.NORTH);
		this.popup.add(ok , BorderLayout.CENTER);
		
		
		this.popup.validate();
		this.popup.repaint();
		this.popup.setVisible(true);
		
	}
	
	//IN&OUT GAME
	
	@Override
	public void showRanking(Ranking ranking) {
		
		Vector<Vector<String>> data = new Vector<Vector<String>>();
		
		Vector<String> columnNames = new Vector<String>();
		columnNames.add("Punteggio");
		columnNames.add("Username");
		columnNames.add("Specie");
		columnNames.add("Stato");
		
		int size = ranking.getPlayers().size();
		
		for (RankingEntry entry : ranking.getRank(size)){
			Vector<String> row = new Vector<String>();
			row.insertElementAt(entry.getScore().toString(), 0);
			row.insertElementAt(entry.getUsername(), 1);
			row.insertElementAt(entry.getSpeciesName(), 2);
			row.insertElementAt(entry.getState().toString(), 3);
			data.add(row);
		}
		
		createPopup(400 , 400 , new BorderLayout());
		
		JPanel southPanel = new JPanel();
		
		JTable table = new JTable(data , columnNames);
		
		JButton ok = new JButton("OK");
		ok.addActionListener(this.actionHandler);
		ok.setActionCommand("closePopup");
		ok.setMaximumSize(new Dimension(80 , 30));
		ok.setPreferredSize(new Dimension(80 , 30));
		
		southPanel.add(ok);
		
		this.popup.add(table , BorderLayout.CENTER);
		this.popup.add(southPanel, BorderLayout.SOUTH);
		this.popup.pack();
		this.popup.setVisible(true);
		
	}

	public void showPlayersList(){
		
		createPopup(200, 400, new BorderLayout());
		
		JPanel topPanel = new JPanel();
		topPanel.setLayout(new BoxLayout(topPanel , BoxLayout.Y_AXIS));
		topPanel.setMaximumSize(new Dimension(200 , 350));
		
		JPanel bottomPanel = new JPanel();
		bottomPanel.setMaximumSize(new Dimension(200 , 50));

		
		JButton ok = new JButton("OK");
		ok.setMaximumSize(new Dimension(80 , 30));
		ok.setPreferredSize(new Dimension(80 , 30));
		ok.addActionListener(this.actionHandler);
		ok.setActionCommand("closePopup");
	
		
		topPanel.add(Box.createRigidArea(new Dimension(0 , 5)));
		Vector<String> list = this.logic.playersList();
		for(String s : list){
			topPanel.add(new JLabel(s));
			topPanel.add(Box.createRigidArea(new Dimension(0 , 5)));
		}
		
		bottomPanel.add(ok);
		
		this.popup.add(topPanel , BorderLayout.CENTER);
		this.popup.add(bottomPanel , BorderLayout.SOUTH);
		
		this.popup.repaint();
		this.popup.validate();
		this.popup.setVisible(true);
		
		
	}
		
	
	//NOTICE
	
	public void refreshInteract(){
		
		FGUI.this.interact.repaint();
		FGUI.this.interact.revalidate();

	}
	
	public void refreshBoard(){
		
		FGUI.this.board.repaint();
		FGUI.this.board.revalidate();

		
	}
	
	public void createPopup(int h_size , int v_size , LayoutManager layout){
		this.popup = new JFrame();
		this.popup.setLayout(layout);
		this.popup.setLocation(this.H_SIZE/2 - h_size/2 , this.V_SIZE/2 - v_size/2);
		this.popup.setMinimumSize(new Dimension(h_size, v_size));
		this.popup.setMaximumSize(new Dimension(h_size, v_size));
		this.popup.setPreferredSize(new Dimension(h_size, v_size));
		this.popup.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	}

	@Override
	public void showExceptionContent(String message) {
		
		this.error = new JFrame();
		this.error.setTitle("ERRORE!");
		this.error.setLayout(new FlowLayout());
		this.error.setLocationRelativeTo(null);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		this.error.setMinimumSize(new Dimension(250, 100));
		this.error.setPreferredSize(new Dimension(250, 100));
		
		JLabel label = new JLabel(message);
		JButton ok = new JButton("OK");
		ok.setActionCommand("closeError");
		ok.addActionListener(this.actionHandler);
		
		this.error.add(label);
		this.error.add(ok);
		this.error.pack();
		this.error.setVisible(true);
	}
	
	
	//ACTION LISTENER
	
	private class ActionHandler implements ActionListener{
		
		@Override
		public void actionPerformed(ActionEvent e) {
			
			if ("closePopup".equals(e.getActionCommand())){
				if (FGUI.this.popup != null)
					FGUI.this.popup.dispose();
			}
			
			else if ("closeError".equals(e.getActionCommand())){
				if (FGUI.this.error != null)
					FGUI.this.error.dispose();
			}
			
			else if ("preLogin".equals(e.getActionCommand())){
				showPreLogin();
			
			}
			
			else if ("register".equals(e.getActionCommand())){
				try{
					JButton ok = (JButton) e.getSource();
					JTextField username = (JTextField)ok.getClientProperty("username");
					JPasswordField passwd = (JPasswordField)ok.getClientProperty("passwd");
					
					FGUI.this.logic.newUser(username.getText(), new String(passwd.getPassword()));
				} catch (Exception ex){
					showExceptionContent(ex.getMessage());
				}
			}
			
			else if ("login".equals(e.getActionCommand())){
				try{
					JButton ok = (JButton) e.getSource();
					JTextField username = (JTextField)ok.getClientProperty("username");
					JPasswordField passwd = (JPasswordField)ok.getClientProperty("passwd");
					
					FGUI.this.logic.login(username.getText(), new String(passwd.getPassword()));
					fillInteract();
					
					FGUI.this.popup.dispose();
				} catch (Exception ex){
					showExceptionContent(ex.getMessage());
				}
			}
			
			else if ("inGame".equals(e.getActionCommand())){
				try{
					FGUI.this.logic.inGame();
					FGUI.this.createMap();
					FGUI.this.logic.startTurns();
					FGUI.this.refreshMap();
					FGUI.this.showPlay();
					FGUI.this.menu.getMenu(0).getItem(1).setEnabled(false);
					FGUI.this.menu.getMenu(0).getItem(2).setEnabled(true);
					FGUI.this.validate();
					FGUI.this.repaint();
				} catch (Exception ex){
					if ("nospecie".equals(ex.getMessage())){
						showNewSpecies();
					}
					else showExceptionContent(ex.getMessage());
				}
			}
			
//			else if ("shownewspecies".equals(e.getActionCommand())){
//				showNewSpecies();
//				FGUI.this.popup.dispose();
//			}
			
			else if ("newSpecies".equals(e.getActionCommand())){
				
				JButton sourceButton = (JButton)e.getSource();
				ButtonGroup speciesTypeSource = (ButtonGroup)sourceButton.getClientProperty("speciesType");
				JTextField speciesNameSource = (JTextField)sourceButton.getClientProperty("speciesName");
				try{
					char type = speciesTypeSource.getSelection().getActionCommand().charAt(0);
					if (type == 'c')
						FGUI.this.myDinoIcon = FGUI.this.DINOCARN;
					else if (type == 'e')
						FGUI.this.myDinoIcon = FGUI.this.DINOHERB;
					
					FGUI.this.logic.newSpecies(speciesNameSource.getText() , type);
					FGUI.this.myDinoIcon = (type == 'c') ? FGUI.this.DINOCARN : FGUI.this.DINOHERB;
			
					FGUI.this.popup.dispose();
					
					// entriamo in gioco
					FGUI.this.logic.inGame();
					FGUI.this.createMap();
					FGUI.this.logic.startTurns();
					FGUI.this.refreshMap();
					FGUI.this.showPlay();
				} catch (Exception ex){
					showExceptionContent(ex.getMessage());
				}
			}
			
			else if ("playersList".equals(e.getActionCommand())){
				try{
					showPlayersList();
				} catch (Exception ex){
					showExceptionContent(ex.getMessage());
				}
			}
			
			else if ("ranking".equals(e.getActionCommand())){
				try{
					showRanking(FGUI.this.logic.ranking());
				} catch(Exception ex){
					showExceptionContent(ex.getMessage());
				}
			}
			
			else if ("outGame".equals(e.getActionCommand())){
				try{
					FGUI.this.logic.outGame();
					FGUI.this.board.removeAll();
					FGUI.this.refreshBoard();
					FGUI.this.menu.getMenu(0).getItem(1).setEnabled(true);
					FGUI.this.menu.getMenu(0).getItem(2).setEnabled(false);
					FGUI.this.validate();
					FGUI.this.repaint();
					for (Component c :FGUI.this.interact.getComponents()){
						if (c instanceof JButton){
							if ("skipTurn".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(false);}
							if ("grow".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(false);}
							if ("egg".equals(((JButton)c).getActionCommand())){((JButton)c).setEnabled(false);}
						}
					}
					FGUI.this.refreshInteract();
					
				} catch(Exception ex){
					showExceptionContent(ex.getMessage());
				}
			}
			
			else if ("useTurn".equals(e.getActionCommand())){
				try{
					FGUI.this.logic.useTurn();
					if (FGUI.this.popup != null)
						FGUI.this.popup.dispose();
					FGUI.this.showPlay();
					
					
				}catch(Exception ex){
					showExceptionContent(ex.getMessage());
				}
			}
			
			else if ("skipTurn".equals(e.getActionCommand())){
				try{
					FGUI.this.logic.skipTurn();
					if (FGUI.this.popup != null)
						FGUI.this.popup.dispose();
					FGUI.this.showPlay();
					
				}catch(Exception ex){
					showExceptionContent(ex.getMessage());
				}
			}
			
		}
 
	}
	
	private class MapHandler implements ActionListener {

		private int currentDino;
		@Override
		public void actionPerformed(ActionEvent e) {
			
			JButton source = (JButton)e.getSource();
			if (e.getActionCommand().equals("")){
				BoxType type = (BoxType)source.getClientProperty("type");
				if (type.equals(BoxType.DINO)){
					FGUI.this.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
					this.currentDino = (Integer)source.getClientProperty("idDino");
					
					for (Component c : FGUI.this.board.getComponents()){
						JButton b = (JButton) c;
						type = (BoxType)b.getClientProperty("type");
						if (BoxType.LAND.equals(type) || BoxType.MEAT.equals(type) || 
								BoxType.VEGE.equals(type) || BoxType.DINO.equals(type))
							b.setActionCommand("moving");
					}
					
					for (Component c : FGUI.this.interact.getComponents()){
						if (c instanceof JButton){
							c.setEnabled(true);
						}
					
					}
					FGUI.this.interact.revalidate();
					FGUI.this.interact.repaint();
				}
			} 
			
			else if (e.getActionCommand().equals("moving")){
				int x = (Integer)source.getClientProperty("x");
				int y = (Integer)source.getClientProperty("y");
				int[] coords = { x, y };
				try{
					if (this.currentDino > 0){
						BoxType type = (BoxType)source.getClientProperty("type");
						if (type.equals(BoxType.DINO) && this.currentDino == (Integer)source.getClientProperty("idDino"))
							return;
						
						FGUI.this.logic.move(this.currentDino, coords);
					}
				
				} catch (ExtinctionException ex){
					FGUI.this.showExtinction();
				} catch (Exception ex){
					FGUI.this.showExceptionContent(ex.getMessage());
				} finally {
					FGUI.this.refreshMap();
					this.currentDino = 0;
					FGUI.this.showPlay();
					FGUI.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
					
				}
					
			} 
			
			else if (e.getActionCommand().equals("egg")){
				try{
					FGUI.this.logic.egg(this.currentDino);
				} catch (ExtinctionException ex){
					FGUI.this.showExtinction();
				} catch (Exception ex){
					FGUI.this.showExceptionContent(ex.getMessage());
				} finally {
					FGUI.this.refreshMap();
					this.currentDino = 0;
					FGUI.this.showPlay();
					FGUI.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
					}
			} 
			
			else if (e.getActionCommand().equals("grow")){
				try{
					FGUI.this.logic.grow(this.currentDino);
			
				} catch (ExtinctionException ex){
					FGUI.this.showExtinction();
				} catch (Exception ex){
					FGUI.this.showExceptionContent(ex.getMessage());
				} finally {
					FGUI.this.refreshMap();
					this.currentDino = 0;
					FGUI.this.showPlay();
					FGUI.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
					}
			}
		}
	}

}
